<?php
declare (strict_types = 1);

namespace app\admin\model;

use think\Model;

/**
 * 操作日志模型
 * Class OperationLog
 * @package app\admin\model
 */
class OperationLog extends Model
{
    protected $table = 'operation_log';
    
    // 自动时间戳
    protected $autoWriteTimestamp = true;
    protected $createTime = 'created_at';
    protected $updateTime = 'updated_at';
    
    // 字段类型转换
    protected $type = [
        'id' => 'integer',
        'status' => 'integer',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];
    
    // 允许批量赋值的字段
    protected $field = [
        'id', 'operator', 'operation', 'target_type', 'target_id', 
        'content', 'ip_address', 'user_agent', 'status', 'created_at', 'updated_at'
    ];
    
    /**
     * 记录操作日志
     */
    public static function log(array $data)
    {
        $log = new self();
        $log->operator = $data['operator'] ?? '';
        $log->operation = $data['operation'] ?? '';
        $log->target_type = $data['target_type'] ?? '';
        $log->target_id = $data['target_id'] ?? '';
        $log->content = $data['content'] ?? '';
        $log->ip_address = $data['ip_address'] ?? '';
        $log->user_agent = $data['user_agent'] ?? '';
        $log->status = $data['status'] ?? 1;
        
        return $log->save();
    }
    
    /**
     * 获取操作日志列表
     */
    public static function getList(int $page = 1, int $limit = 20, array $where = [])
    {
        $query = self::order('created_at', 'desc');
        
        // 添加查询条件
        if (!empty($where['operator'])) {
            $query->where('operator', 'like', '%' . $where['operator'] . '%');
        }
        
        if (!empty($where['operation'])) {
            $query->where('operation', 'like', '%' . $where['operation'] . '%');
        }
        
        if (!empty($where['target_type'])) {
            $query->where('target_type', $where['target_type']);
        }
        
        if (!empty($where['start_time'])) {
            $query->where('created_at', '>=', $where['start_time']);
        }
        
        if (!empty($where['end_time'])) {
            $query->where('created_at', '<=', $where['end_time']);
        }
        
        if (isset($where['status'])) {
            $query->where('status', $where['status']);
        }
        
        $total = $query->count();
        $list = $query->page($page, $limit)->select();
        
        return [
            'total' => $total,
            'list' => $list,
            'page' => $page,
            'limit' => $limit
        ];
    }
    
    /**
     * 获取今日统计
     */
    public static function getTodayStats()
    {
        $today = date('Y-m-d');
        $tomorrow = date('Y-m-d', strtotime('+1 day'));
        
        $stats = self::where('created_at', '>=', $today)
            ->where('created_at', '<', $tomorrow)
            ->field('
                COUNT(*) as total,
                SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as success,
                SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as failed,
                COUNT(DISTINCT operator) as operators
            ')
            ->find();
            
        return $stats ? $stats->toArray() : [
            'total' => 0,
            'success' => 0,
            'failed' => 0,
            'operators' => 0
        ];
    }
    
    /**
     * 获取操作类型统计
     */
    public static function getOperationStats(int $days = 7)
    {
        $startDate = date('Y-m-d', strtotime("-{$days} days"));
        
        $stats = self::where('created_at', '>=', $startDate)
            ->field('operation, COUNT(*) as count')
            ->group('operation')
            ->order('count', 'desc')
            ->select();
            
        return $stats ? $stats->toArray() : [];
    }
    
    /**
     * 清理过期日志
     */
    public static function cleanup(int $days = 30)
    {
        $expireDate = date('Y-m-d H:i:s', strtotime("-{$days} days"));
        
        return self::where('created_at', '<', $expireDate)->delete();
    }
    
    /**
     * 获取操作人列表
     */
    public static function getOperators()
    {
        return self::field('operator')
            ->group('operator')
            ->order('operator')
            ->column('operator');
    }
    
    /**
     * 获取操作类型列表
     */
    public static function getOperations()
    {
        return self::field('operation')
            ->group('operation')
            ->order('operation')
            ->column('operation');
    }
    
    /**
     * 获取目标类型列表
     */
    public static function getTargetTypes()
    {
        return self::field('target_type')
            ->group('target_type')
            ->order('target_type')
            ->column('target_type');
    }
    
    /**
     * 获取最近操作
     */
    public static function getRecent(int $limit = 10)
    {
        return self::order('created_at', 'desc')
            ->limit($limit)
            ->select();
    }
    
    /**
     * 获取操作人统计
     */
    public static function getOperatorStats(int $days = 7)
    {
        $startDate = date('Y-m-d', strtotime("-{$days} days"));
        
        $stats = self::where('created_at', '>=', $startDate)
            ->field('operator, COUNT(*) as count')
            ->group('operator')
            ->order('count', 'desc')
            ->select();
            
        return $stats ? $stats->toArray() : [];
    }
    
    /**
     * 获取IP统计
     */
    public static function getIpStats(int $days = 7)
    {
        $startDate = date('Y-m-d', strtotime("-{$days} days"));
        
        $stats = self::where('created_at', '>=', $startDate)
            ->field('ip_address, COUNT(*) as count')
            ->group('ip_address')
            ->order('count', 'desc')
            ->limit(20)
            ->select();
            
        return $stats ? $stats->toArray() : [];
    }
    
    /**
     * 获取状态统计
     */
    public static function getStatusStats(int $days = 7)
    {
        $startDate = date('Y-m-d', strtotime("-{$days} days"));
        
        $stats = self::where('created_at', '>=', $startDate)
            ->field('status, COUNT(*) as count')
            ->group('status')
            ->select();
            
        $result = [
            'success' => 0,
            'failed' => 0
        ];
        
        if ($stats) {
            foreach ($stats as $stat) {
                if ($stat['status'] == 1) {
                    $result['success'] = $stat['count'];
                } else {
                    $result['failed'] = $stat['count'];
                }
            }
        }
        
        return $result;
    }
}
